#include "tasks.h"

//创建一个任务数组，数组元素为任务结构体
extern Task_t Task_list[];

//创建一个任务数量变量
extern uint8_t Task_num;
//任务状态切换函数,此函数在定时中断中被调用
void Task_switch_handler(void){
    //遍历任务，不是挂起态就执行count--
    //如果任务是挂起态，就跳过本次循环 不执行count--
    for(uint8_t i=0; i<Task_num ; i++){
        //利用结构体指针指向每个任务
        Task_t *task = &Task_list[i];
        if(task->state == TASK_STATE_SUSPEND){
            continue;
        }
        //判断任务的count是否大于0，如果大于0，就执行count--
        //如果count等于0，就将任务状态切换为运行态，执行任务,并重新设置count
        if(task->count)task->count--;
        if(task->count == 0){
            task->state = TASK_STATE_RUN;
            task->count = task->period;
        }
    }
}
//创建任务调度函数，运行在main函数主循环中
void Task_exec_handler(void)
{
    for(uint8_t i=0 ; i<Task_num ; i++)
    {
        Task_t* task = &Task_list[i];
        if(task->state == TASK_STATE_RUN)
        {
            //调用任务执行回调
            task->callback();
            //如果任务状态在callback中被改变，则无需切换为停止态，直接跳过
            if(task->state != TASK_STATE_RUN)continue;
            //任务执行完后，将任务切换为停止态
            task->state = TASK_STATE_STOP;
        }
    }
}

//将任务状态切换为挂起态的函数，执行任务挂起回调函数，参数为任务的索引
void Task_suspend(uint8_t index)
{
    //先判断任务索引是否有效，无效则返回
    if(index >= Task_num)return;
    //获取任务指针
    Task_t *task = &Task_list[index];
    //任务状态切换为挂起态
    task->state = TASK_STATE_SUSPEND;
    //判断本任务是否有挂起回调函数，有则执行任务挂起回调函数
    if(task->callback_suspend != NULL){
    task->callback_suspend();
    }
}
//恢复指定任务函数，参数为任务的索引，重置任务计数器为任务周期
void Task_resume(uint8_t index)
{
    //先判断任务索引是否有效，无效则返回
    if(index >= Task_num)return;
    //获取任务指针
    Task_t *task = &Task_list[index];
    //任务状态切换为运行态
    task->state = TASK_STATE_RUN;
    //任务计数器重置为任务周期
    task->count = task->period;
}
//根据任务函数名，获取任务索引的函数，参数为任务函数名，返回值为任务索引
uint8_t Task_get_index(Task_callback func)
{
    for(uint8_t i = 0; i < Task_num; i++)
    {
        if(Task_list[i].callback == func)
        {
            return i;
        }
    }
    return -1;
}
//根据任务索引，获取任务状态的函数，参数为任务索引，返回值为任务状态
Task_status Task_get_status(uint8_t index)
{
    if(index >= Task_num)return TASK_STATE_STOP;
    return Task_list[index].state;
}


















